---
title: Popover API in UI5 Web Components 2.0
tags: [release, v2, popover API]
slug: /releases/popover-api-in-v2
date: 2024-04-19T10:00
---

UI5 Web Components 2.0 will provide greatly improved popups by taking advantage of the [native browser popover API](https://developer.mozilla.org/en-US/docs/Web/API/Popover_API).

## What is the popover API?

The [popover API](https://developer.mozilla.org/en-US/docs/Web/API/Popover_API) is a browser-native solution to displaying popup-like components (Popovers, Dialogs, etc.).
above all other content, regardless of its HTML structure and CSS applied.

## Popups in **version 1.x**

There used to be a so-called "static area" (`<ui5-static-area>`) - a DOM element directly in the `<body>` where the popups of all components were placed.
This guaranteed that even if the HTML document had `overflow: hidden`, `transform`, or similar CSS rules applied, or the component was in a *stacking context*, its popup would still be positioned correctly.

Example of `ui5-date-picker`'s DOM structure in **v1.24**:

```html
<body>
    <ui5-static-area>
        <ui5-static-area-item> <!-- A static area item, associated with the DatePicker component -->
            #shadow-root
                <ui5-responsive-popover></ui5-responsive-popover> <!-- here goes the Popover part of the DatePicker component -->
        </ui5-static-area-item>
    </ui5-static-area>

    .........

    <div style="transform: translate(12rem, 12rem)"> <!-- a parent node has CSS that normally breaks popup positioning -->
        <ui5-date-picker>
            #shadow-root
                <ui5-input></ui5-input> <!-- The date Input part of the DatePicker component -->
        </ui5-date-picker>
    </div>
</body>
```

As you can see, the component used to be physically divided in two parts:
 - The "main" part (the `ui5-date-picker` tag itself) containing the date selection input
 - The "popover" part (the `ui5-static-area-item` tag, associated with the said date picker) containing the picker (calendar with years/months/days).

## Popups in **version 2.x**

There is no longer need for a "static area" since the browser now ensures the correct positioning of popups thanks to the popover API.

Example of `ui5-date-picker`'s DOM structure in **v2.0**:

```html
<body>
    <div style="transform: translate(12rem, 12rem)"> <!-- a parent node has CSS that normally breaks popup positioning -->
        <ui5-date-picker>
            #shadow-root
                <ui5-input></ui5-input> <!-- The date Input part of the DatePicker component -->
                <ui5-responsive-popover popover="manual"></ui5-responsive-popover> <!-- the Popover part of the DatePicker component -->
        </ui5-date-picker>
    </div>
</body>
```

The component is no longer physically divided in two parts:
 - Both the input and the popover are inside the `ui5-date-picker` itself
 - The popover has the **popover="manual"** attribute (introduced with the popover API) that ensures it will be displayed above anything else on the HTML page.

It's that simple!

## The **practical** benefits

### Simpler and more robust components
    - Easier to develop and maintain.
    - Everything belonging to a component is now in one place! This includes code logic, HTML and CSS.

### Enhanced overstyling capabilities for apps
    - We can now provide [CSS Shadow Parts](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_shadow_parts) also for the "popup part", not just in the "main part" of the component!
    - [CSS Custom Properties](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties) set on the component will also have effect for its "popup part"!

Consider the following example:

```html
<body>
    <style>
        #mc::part(root) {
            background: blue;
        }
        #mc::part(list) {
            margin: 0.5rem;
        }
    </style>

    <my-component id="mc">
        #shadow-root
            <div part="root"></div>
            <ui5-popover>
                <ui5-list part="list"></ui5-list>
            </ui5-popover>
    </my-component>
</body>
```

Since the popover is now part of the component, component authors can provide CSS Shadow Parts for elements in the popover, in addition to the existing CSS Shadow Parts.

### Components with popups can now have physical children

Web components with popups had a **hard limitation** of not being able to slot children to the popup.

Example of `ui5-select`'s (simplified) DOM structure in **v1.24**:

```html
<body>
    <ui5-static-area>
        <ui5-static-area-item> <!-- static area item of the ui5-select -->
            #shadow-root
                <ui5-responsive-popover> <!-- the "dropdown" part of the ui5-select -->
                    <ui5-list> <!-- the list inside ui5-select's dropdown -->
                        <ui5-li text="Option 1"></ui5-li> <!-- list item for the 1st ui5-option -->
                        <ui5-li text="Option 2"></ui5-li> <!-- list item for the 2nd ui5-option -->
                        <ui5-li text="Option 3"></ui5-li> <!-- list item for the 3rd ui5-option -->
                    </ui5-list>
                </ui5-responsive-popover>
        </ui5-static-area-item>
    </ui5-static-area>

    .........

    <ui5-select>
        #shadow-root
            <div></div> <!-- The "box" part of the select -->

        <ui5-option>Option 1</ui5-option>
        <ui5-option>Option 2</ui5-option>
        <ui5-option>Option 3</ui5-option>
    </ui5-select>

</body>
```

As you can clearly see from the example, there is no way to **slot** the `ui5-option` components into the `ui5-list` as it is in a completely different part of the DOM, due to the need for a static area.
Instead, we can only provide **logical** `ui5-option` components and just use their **text content** for the `text` property of the list items (`ui5-li`) in the static area.

Example of `ui5-select`'s (simplified) DOM structure in **v2.0**:

```html
<body>
    <ui5-select>
        #shadow-root
            <div></div> <!-- The "box" part of the select -->
            <ui5-responsive-popover> <!-- the "dropdown" part of the ui5-select -->
                <ui5-list> <!-- the list inside ui5-select's dropdown -->
                    <slot></slot>
                </ui5-list>
            </ui5-responsive-popover>

        <ui5-option><strong>Option</strong> 1</ui5-option>
        <ui5-option><ui5-icon name="accept"></ui5-icon> Option 2</ui5-option>
        <ui5-option><i>Option 3</i></ui5-option>
    </ui5-select>

</body>
```

Now that the popover is part of the `ui5-select` itself, it's possible to have **physical** `ui5-option`s and slot their content directly into the popover or its children (`ui5-list` in this example).

This allows us to provide support for **custom user content** for components that had strict predefined APIs in the past!

### Easier testing for both apps and component package authors
    - Tests no longer need to know how to find the static area item, associated with a given component - everything is directly in the shadow root!
    - Writing tests is much simplified.

### Cross-framework popup compatibility for the future
    - Frameworks who use the native browser popover API no longer need to synchronize themselves (negotiate `z-index` values, etc.).
    - The last popup to be opened will always be on top (guarnateed by the browser)!

## When can I start using it?
    - The current versions of all supported browsers (Chrome, Safari, Edge, and now also Firefox as of version 125) fully support the popover API. [See Can I Use report](https://caniuse.com/?search=popover).
    - By the time **v2.0** is officially released (we are at **v2.0-r.c.2** as of writing this blog post) we expect that each major browser will have already released at least 3 stable versions since the introduction of the popover API.

Make sure to check our blog for future announcements, including the official release date of **UI5 Web Components 2.0**!